package demo12

// 模板设计模式 类似继承 类似装饰器但有所不同
import "fmt"
// templatemethod 抽象层
type Downloader interface{
	Download(uri string)
}
// 结构体
type template struct{
	implement
	uri string
}

// 模板
type implement interface{
	save()
	download()
}

func NewTemplate(impl implement) *template{
	return &template{
		implement:impl,
	}
}

// 所有的逻辑动作在这里调用和实现
func (i *template)Download(uri string){
	i.uri = uri
	fmt.Println("prepare downlading")
	i.implement.download()
	i.implement.save()
	fmt.Println("finish downloading")
}

func (i *template)save(){
	fmt.Println("default save...")
}

// 下载器
type HTTPDownloader struct{
	*template
}

func NewHTTPDownloader() Downloader{
	downloader := &HTTPDownloader{}
	// 继承父类，但需要匿名，同时需要把对象赋值
	template := NewTemplate(downloader)
	downloader.template = template
	return downloader
}

func (d *HTTPDownloader) download(){
	fmt.Printf("download %s via http\n",d.uri)
}

func (*HTTPDownloader)save(){
	fmt.Println("http save")
}

type FTPDownloader struct{
	*template
}

func NewFTPDownloader() Downloader{
	downloader := &FTPDownloader{}
	template := NewTemplate(downloader)
	downloader.template = template
	return template
}

func (d *FTPDownloader)download(){
	fmt.Printf("download %s via ftp\n",d.uri)
}
// func (*FTPDownloader)save(){
// 	fmt.Println("ftp save")
// }